﻿@{
    ViewBag.Title = "Admin";
}

<link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css">

<div style="position: absolute; top: 10px; right: 10px;">
    Logged in as @ViewBag.UserName
    [<a href="#" class="btn-link" data-bind="click: signOut">Sign Out</a>]
</div>

<script src="https://login.persona.org/include.js"></script>
<div style="width: 90%; margin-left: auto; margin-right: auto; margin-top: 150px;">

    <button class="btn" data-bind="click: upload">Upload new songs</button>
    <input type="text" data-bind="value: rawSearch, valueUpdate: 'keyup'" placeholder="Search for music" style="margin-top: 10px;" />
    <div style="margin-left: 20px; padding-top: 20px;" data-bind="visible: pendingChangesCount() > 0">
        <span id="spinner"></span>
        <label style="margin-left: 20px;" data-bind="text: pendingUploadText"></label>
    </div>
    <div>
        <a href="#" data-bind="visible: skip() > 0, click: previous">Previous</a>
        <span data-bind="visible: skip() > 0 && songs().length == maxResults">&nbsp; | &nbsp;</span>
        <a href="#" data-bind="visible: songs().length == maxResults, click: next">Next</a>
    </div>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Edit</th>
                <th>Id</th>
                <th>Artist</th>
                <th>Name</th>
                <th>Album</th>
                <th>Song Number</th>
                <th>Community Rank</th>
                <th>File Name</th>
                <th>Delete</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: songs">
            <tr>
                <td>
                    <a href="#" data-bind="click: $root.editSong">Edit</a>
                </td>
                <td data-bind="text: Id"></td>
                <td data-bind="text: Artist"></td>
                <td data-bind="text: Name"></td>
                <td data-bind="text: Album"></td>
                <td data-bind="text: Number"></td>
                <td data-bind="text: CommunityRank"></td>
                <td data-bind="text: FileName"></td>
                <td>
                    <a href="#" data-bind="click: $root.confirmDeleteSong, visible: !isConfirmingDelete()">Delete</a>
                    <a href="#" class="alert-error" data-bind="click: $root.deleteSong, visible: isConfirmingDelete">Yes, delete.</a>
                </td>
            </tr>
        </tbody>
    </table>

    <div id="editSong" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-bind="with: editedSong">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 data-bind="text: 'Edit ' + Name"></h3>
        </div>
        <div class="modal-body">
            <label>Name: </label>
            <input type="text" data-bind="value: Name" />
            <br />
            <label>Artist: </label>
            <input type="text" data-bind="value: Artist" />
            <br />
            <label>Album: </label>
            <input type="text" data-bind="value: Album" />
            <br />
            <label>Number: </label>
            <input type="text" data-bind="value: Number" />
            <br />
            <label>Community Rank: </label>
            <input type="text" data-bind="value: CommunityRank" />
            <br />
            <label>FileName: </label>
            <input type="text" data-bind="value: FileName" />
        </div>
        <div class="modal-footer">
            <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
            <button class="btn btn-primary" data-dismiss="modal" data-bind="click: $root.saveSong">Save changes</button>
        </div>
    </div>

    <div id="pendingSongUploadDialog" class="modal hide fade" tabindex="-1" role="dialog" data-bind="with: editedSong">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 data-bind="text: 'Edit ' + Name"></h3>
        </div>
        <div class="modal-body">
            <label>Name: </label>
            <input type="text" data-bind="value: Name" />
        </div>
        <div class="modal-footer">
            <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
            <button class="btn btn-primary" data-dismiss="modal" data-bind="click: $root.saveSong">Save changes</button>
        </div>
    </div>

    <div>
        <a href="#" data-bind="visible: skip() > 0, click: previous">Previous</a>
        <span data-bind="visible: skip() > 0 && songs().length == maxResults">&nbsp; | &nbsp;</span>
        <a href="#" data-bind="visible: songs().length == maxResults, click: next">Next</a>
    </div>
</div>

<script src="@Url.Content("~/Scripts/spin.js")" type="text/javascript"></script>
<script src="http://api.filepicker.io/v1/filepicker.js" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-postbox.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/bootstrap.min.js")" type="text/javascript"></script>
<script type="text/javascript">

    $(function () {

        filepicker.setKey('AGzDBqLIiRL9UJUPtLZ8Az');

        var viewModel = {
            editedSong: ko.observable(),
            songs: ko.observableArray().subscribeTo("AdminSongsProcessed"),
            pendingChangesCount: ko.observable(0),
            skip: ko.observable(0),
            take: ko.observable(20),
            maxResults: 20,
            rawSearch: ko.observable(),

            upload: function () {

                var filePickerOptions = {
                    extension: '.mp3',
                    container: 'modal',
                    'services': [
                        'COMPUTER',
                        'DROPBOX',
                        'URL',
                        'GOOGLE_DRIVE',
                        'GMAIL'
                    ]
                };

                filepicker.pickMultiple(filePickerOptions, function (uploadedFiles) {                    
                    // This function is invoked when the files finish uploading.
                    // We're passed uploadedFiles, which is an array of objects that look like this:
                    // { url: "http://filepickerserver/asdfqw35134", size: 12342134, type: "audio/mpeg", filename: "foo.mp3" }
                    uploadedFiles.forEach(function (file) {
                        var postArgs = { url: "/Admin/UploadSong?address=" + file.url + "&fileName=" + file.filename, responseMessage: "SongUploadCompleted" };
                        ko.postbox.publish("POST", postArgs);
                        viewModel.pendingChangesCount(viewModel.pendingChangesCount() + 1);
                    });
                });
            },

            editSong: function (song) {
                viewModel.editedSong(song);
                $('#editSong').modal();
            },

            saveSong: function (song) {
                $('#editSong').modal({ show: false });
                ko.postbox.publish("POST", { url: "/Admin/SaveSong", data: JSON.stringify(song), responseMessage: "SongEditCompleted" });
                viewModel.pendingChangesCount(viewModel.pendingChangesCount() + 1);
            },

            confirmDeleteSong: function (song) {
                song.isConfirmingDelete(true);
            },

            deleteSong: function (song) {
                ko.postbox.publish("POST", { url: "/Admin/DeleteSong?id=" + song.Id, responseMessage: "SongDeleteCompleted" });
                viewModel.pendingChangesCount(viewModel.pendingChangesCount() + 1);
            },

            signOut: function () {
                navigator.id.logout();
            },

            fetchSongs: function () {
                ko.postbox.publish("GET", {
                    url: "/Admin/GetSongs",
                    data: { search: viewModel.throttledSearch(), skip: viewModel.skip(), take: viewModel.take() },
                    responseMessage: "AdminSongsFetched"
                });
            },

            next: function () {
                viewModel.skip(viewModel.skip() + viewModel.maxResults);
                viewModel.fetchSongs();
            },

            previous: function () {
                var newSkip = Math.max(0, viewModel.skip() - viewModel.maxResults);
                viewModel.skip(newSkip);
                viewModel.fetchSongs();
            }
        };

        // Subscriptions
        ko.postbox.subscribe("SongEditCompleted", function () { ko.postbox.publish("AdminChangeCompleted") });
        ko.postbox.subscribe("SongDeleteCompleted", function () { ko.postbox.publish("AdminChangeCompleted") });
        ko.postbox.subscribe("SongUploadCompleted", function () { ko.postbox.publish("AdminChangeCompleted") });
        ko.postbox.subscribe("AdminSongsFetched", function (songs) {
            songs.forEach(function (s) {
                s.isConfirmingDelete = ko.observable(false);
            });

            ko.postbox.publish("AdminSongsProcessed", songs);
        });
        ko.postbox.subscribe("AdminChangeCompleted", function () {
            viewModel.pendingChangesCount(Math.max(0, viewModel.pendingChangesCount() - 1));
            viewModel.fetchSongs();
        });
        ko.postbox.subscribe("GET", function (args) {
            args.type = "GET";
            ko.postbox.publish("AJAX", args);
        });
        ko.postbox.subscribe("POST", function (args) {
            args.type = "POST";
            ko.postbox.publish("AJAX", args);
        });
        ko.postbox.subscribe("AJAX", function (args) {
            $.ajax({
                type: args.type,
                url: args.url,
                data: args.data,
                dataType: 'json',
                contentType: "application/json; charset=utf-8",
                cache: args.type == "GET" ? false : undefined
            }).success(function (result) {
                if (args.responseMessage) {
                    ko.postbox.publish(args.responseMessage, result);
                }
            })
            .fail(function (jqXHR, textStatus, errorThrown) {
                console.log(args.type + " call failed.", args, jqXHR, textStatus, errorThrown);
            });
        });
        
        // Computeds
        viewModel.pendingUploadText = ko.computed(function () {
            return viewModel.pendingChangesCount() == 1 ? "Processing your change, feel free to keep working." : "Processing your " + viewModel.pendingChangesCount() + " changes. Feel free to keep working.";
        });

        viewModel.throttledSearch = ko.computed(function () {
            return viewModel.rawSearch();
        }).extend({ throttle: 250 });
        viewModel.throttledSearch.subscribe(function (search) {
            viewModel.skip(0);
            viewModel.fetchSongs();
        });

        ko.applyBindings(viewModel);
        viewModel.fetchSongs();

        // Setup the loading upload spinner.
        var opts = { lines: 10, width: 4, radius: 2, corners: 1, rotate: 0, color: '#08C', speed: 1.6, trail: 15, shadow: true, hwaccel: true, className: 'spinner', zIndex: 2e9, top: 'auto',  left: 'auto' };
        var target = document.getElementById('spinner');
        var spinner = new Spinner(opts).spin(target);
        
        // Persona logout watcher.
        navigator.id.watch({
            onlogin: function () { },
            onlogout: function () {
                $.ajax({
                    type: 'POST',
                    url: '/Admin/Logout',
                    success: function (res, status, xhr) { window.location.reload(); },
                    error: function (res, status, xhr) { alert("logout failure " + res); }
                });
            }
        });
    });

</script>